package com.stud.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.stud.common.exception.ServiceException;
import com.stud.common.jdbc.MyJdbcTemplate;
import com.stud.common.mybatis.BaseServiceImpl;
import com.stud.system.domain.Area;
import com.stud.system.dto.AreaDTO;
import com.stud.system.factory.AreaSqlFactory;
import com.stud.system.mapper.AreaMapper;
import com.stud.system.service.AreaService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 区域管理Service业务层处理
 *
 * @author Stud
 * @date 2023-07-27
 */
@Service
@RequiredArgsConstructor
public class AreaServiceImpl extends BaseServiceImpl<AreaMapper, Area> implements AreaService {
    private final MyJdbcTemplate jdbcTemplate;

    /**
     * 递归获取所有下级区域
     *
     * @param areaId
     * @return
     */
    @Override
    public List<AreaDTO> recurseChildren(Long areaId) {
        String sql = AreaSqlFactory.recurseDown(areaId);
        log.debug("递归查询所有下级区域==" + sql);
        List<AreaDTO> areaDtoList = this.jdbcTemplate.select(sql, AreaDTO.class);
        return areaDtoList;
    }

    /**
     * 递归获取所有下级区域
     *
     * @param areaId
     * @return
     */
    @Override
    public List<Long> recurseChildrenId(Long areaId) {
        String sql = AreaSqlFactory.recurseDownForId(areaId);
        log.debug("递归查询所有下级区域ID==" + sql);
        return this.jdbcTemplate.selectSingleColumn(sql, Long.class);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Area area) {
        initAreaFullPath(area);

        if (Objects.equals(area.getParentId(), 8L)) {
            area.setDistrictName(area.getDistrictName());
            super.save(area);
            area.setDistrictId(area.getId());
            return super.update(area);
        }

        Area parent = this.getById(area.getParentId());

        if (Objects.isNull(parent) || Objects.isNull(parent.getDistrictId())) {
            throw new ServiceException("上级区域数据异常");
        }

        area.setDistrictId(parent.getDistrictId());
        area.setDistrictName(parent.getDistrictName());

        return super.save(area);
    }

    @Override
    public boolean update(Area area) {

        if (Objects.equals(area.getParentId(), 8L)) {
            area.setDistrictId(area.getId());
            area.setDistrictName(area.getDistrictName());
        } else {
            Area parent = this.getById(area.getParentId());
            if (Objects.isNull(parent) || Objects.isNull(parent.getDistrictId())) {
                throw new ServiceException("上级区域数据异常");
            }
            area.setDistrictId(parent.getDistrictId());
            area.setDistrictName(parent.getDistrictName());
        }

        Area dbArea = this.getById(area.getId());
        if (!Objects.equals(area.getParentId(), dbArea.getParentId())) {
            initAreaFullPath(area);
            this.jdbcTemplate.execute(" update t_project set area_full_path = '" + area.getAreaFullPath() + "' where area_id = " + area.getId());
        }

        return super.update(area);
    }

    @Override
    public List<Area> districtList() {
        LambdaQueryWrapper<Area> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Area::getParentId, 8L);
        return this.list(wrapper);
    }

    private void initAreaFullPath(Area area) {
        if (Objects.isNull(area) || Objects.isNull(area.getParentId())) {
            return;
        }
        String sql = AreaSqlFactory.recurseUpName(area.getParentId());

        List<String> areaNameList = this.jdbcTemplate.selectSingleColumn(sql);

        StringBuilder sb = new StringBuilder();
        for (int i = areaNameList.size() - 1; i >= 0; i--) {
            if (Objects.equals(areaNameList.get(i), "徐州市")) {
                continue;
            }
            sb.append(areaNameList.get(i) + " ");
        }
        sb.append(area.getAreaName());
        area.setAreaFullPath(sb.toString());
    }
}
